library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;

-- synopsys translate_off
-- synthesis translate_off
--library csx_HRDLIB_FTSM;
-- use csx_HRDLIB_FTSM.VCOMPONENTS.all;
-- synthesis translate_on
-- synopsys translate_on

library work;
    use work.router_pack.all;


-------------------------------------------------------------------------------
entity tb_msl_router is
-------------------------------------------------------------------------------
-- empty
-------------------------------------------------------------------------------
end tb_msl_router ;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
architecture tb_msl_router_arch of tb_msl_router is
-------------------------------------------------------------------------------

constant add_delay_on_reqo_c : time := 0.1 ns;

component msl_router
port(
       -- General Signlas: --
       RESET           : in  std_logic; 
       
       -- Input Ports i/f: --
       RI              : in  std_logic_vector(num_of_ports_con downto 0);
       AI              : out std_logic_vector(num_of_ports_con downto 0);
       --DI              : in  msl_router_mult_ports_data_bus_type;
       DI              : in  std_logic_vector(64 downto 0);
       
       -- Output Ports i/f: --
       RO              : out std_logic_vector(num_of_ports_con downto 0);
       AO              : in  std_logic_vector(num_of_ports_con downto 0);
       --DO              : out msl_router_mult_ports_data_bus_type
       DO              : out std_logic_vector(64 downto 0)
    );  
end component;

signal       RESET           :   std_logic; 
       
signal       RI              :   std_logic_vector(num_of_ports_con downto 0);
signal       AI              :   std_logic_vector(num_of_ports_con downto 0);
--signal       DI              :   msl_router_mult_ports_data_bus_type;
signal       DI              :   std_logic_vector(64 downto 0);
       
signal       RO              :   std_logic_vector(num_of_ports_con downto 0);
signal       AO              :   std_logic_vector(num_of_ports_con downto 0);
--signal       DO              :   msl_router_mult_ports_data_bus_type;
signal       DO              :   std_logic_vector(64 downto 0);

signal       RI2              :   std_logic_vector(num_of_ports_con downto 0);
signal       AI2              :   std_logic_vector(num_of_ports_con downto 0);
--signal       DI2              :   msl_router_mult_ports_data_bus_type;
signal       DI2              :   std_logic_vector(64 downto 0);
       
signal       RO2              :   std_logic_vector(num_of_ports_con downto 0);
signal       AO2              :   std_logic_vector(num_of_ports_con downto 0);
--signal       DO2              :   msl_router_mult_ports_data_bus_type;
signal       DO2              :   std_logic_vector(64 downto 0);

signal clk : std_logic := '0';
signal cnt : integer;

 
alias DI_P0: std_logic_vector(12 downto 0) is DI(64 downto 52);
alias DI_P1: std_logic_vector(12 downto 0) is DI(51 downto 39);
alias DI_P2: std_logic_vector(12 downto 0) is DI(38 downto 26);
alias DI_P3: std_logic_vector(12 downto 0) is DI(25 downto 13);
alias DI_P4: std_logic_vector(12 downto 0) is DI(12 downto 0);

alias DO_P0: std_logic_vector(12 downto 0) is DO(64 downto 52);
alias DO_P1: std_logic_vector(12 downto 0) is DO(51 downto 39);
alias DO_P2: std_logic_vector(12 downto 0) is DO(38 downto 26);
alias DO_P3: std_logic_vector(12 downto 0) is DO(25 downto 13);
alias DO_P4: std_logic_vector(12 downto 0) is DO(12 downto 0);

alias DI2_P0: std_logic_vector(12 downto 0) is DI2(64 downto 52);
alias DI2_P1: std_logic_vector(12 downto 0) is DI2(51 downto 39);
alias DI2_P2: std_logic_vector(12 downto 0) is DI2(38 downto 26);
alias DI2_P3: std_logic_vector(12 downto 0) is DI2(25 downto 13);
alias DI2_P4: std_logic_vector(12 downto 0) is DI2(12 downto 0);

alias DO2_P0: std_logic_vector(12 downto 0) is DO2(64 downto 52);
alias DO2_P1: std_logic_vector(12 downto 0) is DO2(51 downto 39);
alias DO2_P2: std_logic_vector(12 downto 0) is DO2(38 downto 26);
alias DO2_P3: std_logic_vector(12 downto 0) is DO2(25 downto 13);
alias DO2_P4: std_logic_vector(12 downto 0) is DO2(12 downto 0);

signal DI_P0s: std_logic_vector(12 downto 0);
signal DI_P1s: std_logic_vector(12 downto 0);
signal DI_P2s: std_logic_vector(12 downto 0);
signal DI_P3s: std_logic_vector(12 downto 0);
signal DI_P4s: std_logic_vector(12 downto 0);

signal DO_P0s: std_logic_vector(12 downto 0);
signal DO_P1s: std_logic_vector(12 downto 0);
signal DO_P2s: std_logic_vector(12 downto 0);
signal DO_P3s: std_logic_vector(12 downto 0);
signal DO_P4s: std_logic_vector(12 downto 0);

signal DI2_P0s: std_logic_vector(12 downto 0);
signal DI2_P1s: std_logic_vector(12 downto 0);
signal DI2_P2s: std_logic_vector(12 downto 0);
signal DI2_P3s: std_logic_vector(12 downto 0);
signal DI2_P4s: std_logic_vector(12 downto 0);

signal DO2_P0s: std_logic_vector(12 downto 0);
signal DO2_P1s: std_logic_vector(12 downto 0);
signal DO2_P2s: std_logic_vector(12 downto 0);
signal DO2_P3s: std_logic_vector(12 downto 0);
signal DO2_P4s: std_logic_vector(12 downto 0);

signal ri_int : std_logic;
signal di_int: std_logic_vector(12 downto 0);

begin 

 DI_P0s<=DI_P0 ;
 DI_P1s<=DI_P1 ;
 DI_P2s<=DI_P2 ;
 DI_P3s<=DI_P3 ;
 DI_P4s<=DI_P4 ;

 DO_P0s<= DO_P0;
 DO_P1s<= DO_P1;
 DO_P2s<= DO_P2;
 DO_P3s<= DO_P3;
 DO_P4s<= DO_P4;

 DI2_P0s<= DI2_P0;
 DI2_P1s<= DI2_P1;
 DI2_P2s<= DI2_P2;
 DI2_P3s<= DI2_P3;
 DI2_P4s<= DI2_P4;

 DO2_P0s<= DO2_P0;
 DO2_P1s<= DO2_P1;
 DO2_P2s<= DO2_P2;
 DO2_P3s<= DO2_P3;
 DO2_P4s<= DO2_P4;


u_msl_router: msl_router
port map(
       RESET           => RESET, 
       
       RI              => RI,
       AI              => AI,
       DI              => DI,
       
       RO              => RO,
       AO              => AO,
       DO              => DO
);  


u_msl_router2: msl_router
port map(
       RESET           => RESET, 
       
       RI              => RI2,
       AI              => AI2,
       DI              => DI2,
       
       RO              => RO2,
       AO              => AO2,
       DO              => DO2
);

--proc_asym_delay_line: process( RO )
--begin
--  
--  if ( RO(4)'event and RO(4)='1' ) then
--   RI2(0) <= RO(4) after 5.5 ns;
--  end if;
--     
--  if ( RO(4)'event and RO(4)='0' ) then
--   RI2(0) <= RO(4);
--  end if;
--     
--end process;

-- Router1 port4 is connected to port0 of router2.
RI(0) <= ri_int;
DI_P0 <= di_int;
-- Important, don't remove the delay below.
RI2(0) <= RO(4); -- after add_delay_on_reqo_c; -- additional delay on the request to match data coming out of OP.  
AO(4)  <= AI2(0);
DI2_P0 <= DO_P4;

-- Router2 port4 is connected to port1 of router1.
RI(2) <= RO2(4); -- after add_delay_on_reqo_c; -- additional delay on the request to match data coming out of OP.
DI_P2 <= DO2_P4;
AO2(4) <= AI(2);

-- Constant values: --
-- Router 1: --
RI(1) <= '0';
RI(3) <= '0';
RI(4) <= '0';
AO(3 downto 0) <= RO(3 downto 0); -- after add_delay_on_reqo_c; -- additional delay on the request to match data coming out of OP.

DI_P1 <= (others=>'0');
DI_P3 <= (others=>'0');
DI_P4 <= (others=>'0');

-- Router 2: --
DI2_P1 <= (others=>'0');
DI2_P2 <= (others=>'0');
DI2_P3 <= (others=>'0');
DI2_P4 <= (others=>'0');

RI2(4 downto 1) <= (others=>'0'); -- all, but port #0
AO2(3 downto 0) <= RO2(3 downto 0); -- after add_delay_on_reqo_c; -- additional delay on the request to match data coming out of OP.;   

-- Router1, port0, in-interface.
clk_proc: process(RESET, clk)
begin
 if (RESET = '1' ) then
  ri_int <= '0';
  di_int <= (others=>'0');

  cnt <= 0;

 elsif ( clk'event and clk='1' ) then
  cnt <= cnt + 1;

  case cnt is
   when 9 =>
    di_int <= "0010111110111";  -- Router=1, Port0, Vc=0, Sl=1, Header (First Router=OP4, Second=OP4, Third=OP2)

   when 10 =>
    ri_int <= '1';

   when 11 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;


   when 12 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;                      
     else
       cnt <= cnt; -- wait here.
     end if;
----------------------------
   when 13 =>
     di_int <= "0010011100001";  -- Router=1, Port0, VC=0, Sl=1, Body.1 
     
   when 14 =>
     ri_int <= '1';

   when 15 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 16 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;
     
----------------------------
   when 17 =>
     di_int <= "0010011100010";  -- Router=1, Port0, VC=0, Sl=1, Body2
     
   when 18 =>
     ri_int <= '1';

   when 19 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 20 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;
     

----------------------------
   when 21 =>
     di_int <= "0010011100011";  -- Router=1, Port0, VC=0, Sl=1, Body3
     
   when 22 =>
     ri_int <= '1';

   when 23 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 24 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;


----------------------------
   when 25 =>    
     di_int <= "0010011100100";  -- Router=1, Port0, VC=0, Sl=1, Body4
     
   when 26 =>
     ri_int <= '1';

   when 27 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 28 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;



----------------------------5 body
   when 29 =>   
     di_int <= "0010011100101";  -- Router=1, Port0, VC=0, Sl=1, Body4
     
   when 30 =>
     ri_int <= '1';

   when 31 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 32 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;
----------------------------6 body
   when 33 =>   
     di_int <= "0010011100110";  -- Router=1, Port0, VC=0, Sl=1, Body4
     
   when 34 =>
     ri_int <= '1';

   when 35 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 36 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;

----------------------------7 body
   when 37 =>
     di_int <= "0010011100111";  -- Router=1, Port0, VC=0, Sl=1, Body4
     
   when 38 =>
     ri_int <= '1';

   when 39 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 40 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;
----------------------------
   when 41 =>
     di_int <= "0011011111111";  -- Router=1, Port0, VC=0, Sl=1, Tail
     
   when 42 =>
     ri_int <= '1';

   when 43 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 44 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;


------------------------------------------------
-- Second Pack: ----
-- Second pack: header: --
   when 100 =>
    di_int <= "0010111110111";  -- Router=1, Port0, Vc=1, Sl=3, Header (First Router=OP4, Second=OP4, Third=OP2)

   when 101 =>
    ri_int <= '1';

   when 102 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;

   when 103 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;                      
     else
       cnt <= cnt; -- wait here.
     end if;

----------------------------
   when 104 =>
     di_int <= "0010011111111";  -- Router=1, Port0, VC=1, Sl=4, Body
                
   when 105 =>
     ri_int <= '1';

   when 106 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 107 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;
     

----------------------------
   when 108 =>
     di_int <= "0011011111111";  -- Router=1, Port0, VC=1, Sl=4, Tail
     
   when 109 =>
     ri_int <= '1';

   when 110 =>
     if ( AI(0) = '1' ) then
       ri_int <= '0';
     else
       cnt <= cnt; -- wait here.
     end if;
  
   when 111 =>
     if ( AI(0) = '0' ) then
       cnt <= cnt + 1;
     else
       cnt <= cnt; -- wait here.
     end if;


   when others=> NULL;
  end case;

 end if;
end process;

RESET <= '1', '0' after 200 ns;
clk <= not clk after 0.01 ns;



-------------------------------------------------------------------------------
end tb_msl_router_arch;
-------------------------------------------------------------------------------                 

   
-------------------------------------------------------------------------------
configuration  tb_msl_router_cfg  of tb_msl_router is
-------------------------------------------------------------------------------
   for tb_msl_router_arch
   end for;
-------------------------------------------------------------------------------
end  tb_msl_router_cfg;              
-------------------------------------------------------------------------------
                 
